Translation Agent and specs

Rishabh Jain 12 years ago
parent
commit
3c57352f64

+ 1 - 1
app/models/agents/sentiment_agent.rb

@@ -8,7 +8,7 @@ module Agents
8 8
 
9 9
         description <<-MD
10 10
             The SentimentAgent generates `good-bad` (psychological valence or happiness index), `active-passive` (arousal),
11
-            and  `strong-weak` (dominance) score. It will output a value between 1 and 9.
11
+            and  `strong-weak` (dominance) score. It will output a value between 1 and 9. It will only work on English content.
12 12
 
13 13
             Make sure the content this agent is analyzing have sufficient length to get respectable results.
14 14
 

+ 74 - 0
app/models/agents/translation_agent.rb

@@ -0,0 +1,74 @@
1
+module Agents
2
+    class TranslationAgent < Agent
3
+
4
+        cannot_be_scheduled!
5
+
6
+        description <<-MD
7
+            You can use Translation Agent to translate text between natural languages. 
8
+            Services are provided using Microsoft Translator. You can [sign up](https://datamarket.azure.com/dataset/bing/microsofttranslator) and [register your application](https://datamarket.azure.com/developer/applications/register) to get `client_id` and `client_secret` which are required to use this agent.
9
+            `to` must be filled with a [translator language code](http://msdn.microsoft.com/en-us/library/hh456380.aspx).
10
+
11
+            Specify what you would like to translate in `content` field, by specifying key and JSONPath of content to be translated.
12
+
13
+            `expected_receive_period_in_days` is the maximum number of days you would allow to pass between events.
14
+        MD
15
+
16
+        event_description <<-MD
17
+            User defined
18
+        MD
19
+
20
+        def default_options
21
+            {
22
+                :client_id     => "xxxxxx",
23
+                :client_secret => "xxxxxx" ,
24
+                :to            => "fi",
25
+                :expected_receive_period_in_days => 1,
26
+                :content       => {
27
+                    :text => "$.message.text",
28
+                    :content => "$.xyz"
29
+                }
30
+            }
31
+        end
32
+
33
+        def working?
34
+            last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago
35
+        end
36
+
37
+        def translate(text,to,access_token)
38
+            translate_uri = URI "http://api.microsofttranslator.com/v2/Ajax.svc/Translate"
39
+            params = {
40
+                :text => text,
41
+                :to   => to
42
+            }
43
+            translate_uri.query = URI.encode_www_form params
44
+            request = Net::HTTP::Get.new translate_uri
45
+            request['Authorization'] = "Bearer" + " " + access_token
46
+            http = Net::HTTP.new translate_uri.hostname, translate_uri.port 
47
+            response = http.request request 
48
+            YAML.load response.body
49
+        end
50
+
51
+        def validate_options
52
+            unless options[:client_id].present? && options[:client_secret].present? && options[:to].present? && options[:content].present? && options[:expected_receive_period_in_days].present?
53
+                errors.add :base, "client_id,client_secret,to,expected_receive_period_in_days and content are all required"
54
+            end
55
+        end
56
+
57
+        def receive(incoming_events)
58
+            auth_uri = URI "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
59
+            response = Net::HTTP.post_form auth_uri, :client_id => options[:client_id], 
60
+                                                     :client_secret => options[:client_secret], 
61
+                                                     :scope => "http://api.microsofttranslator.com", 
62
+                                                     :grant_type =>  "client_credentials"
63
+            access_token = JSON.parse(response.body)["access_token"]
64
+            incoming_events.each do |event|
65
+                translated_event = {}
66
+                options[:content].each_pair do |key,value|
67
+                    translate_value = Utils.values_at event.payload, value 
68
+                    translated_event[key] = translate translate_value.first, options[:to], access_token
69
+                end
70
+                create_event :payload => translated_event
71
+            end
72
+        end
73
+    end
74
+end

+ 1 - 1
app/models/agents/twilio_agent.rb

@@ -7,7 +7,7 @@ module Agents
7 7
     description <<-MD
8 8
       The TwilioAgent receives and collects events and sends them via text message when scheduled.
9 9
 
10
-      It is assumed that events have a `:message`, `:text`, or `:sms` key, the value of which is sent as the content of the text message.
10
+      It is assumed that events have a `:message`, `:text`, or `:sms` key, the value of which is sent as the content of the text message. You can use Event Formatting Agent if your event does not provide these keys.
11 11
 
12 12
       Set `receiver_cell` to the number to receive text messages and `sender_cell` to the number sending them.
13 13
 

+ 92 - 0
spec/models/agents/translation_agent_spec.rb

@@ -0,0 +1,92 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::TranslationAgent do
4
+    before do
5
+        @valid_params = {
6
+            :name    => "somename",
7
+            :options => {           
8
+                :client_id     => "xxxxxx",
9
+                :client_secret => "xxxxxx" ,
10
+                :to            => "fi",
11
+                :expected_receive_period_in_days => 1,
12
+                :content       => {
13
+                    :text => "$.message",
14
+                    :content => "$.xyz"
15
+                }
16
+            }
17
+        }
18
+
19
+        @checker = Agents::TranslationAgent.new(@valid_params)
20
+        @checker.user = users(:jane)
21
+        @checker.save!
22
+
23
+        @event = Event.new
24
+        @event.agent = agents(:jane_weather_agent)
25
+        @event.payload = {
26
+            :message => "somevalue",
27
+            :xyz => "someothervalue"
28
+        }
29
+
30
+        stub_request(:any, /microsoft/).to_return(:body => "response", :status => 200)
31
+        stub_request(:any, /windows/).to_return(:body => JSON.dump({
32
+            :access_token => 'xxx'}), :status => 200)
33
+
34
+    end
35
+
36
+    describe "#receive" do
37
+        it "checks if it can handle multiple events" do
38
+            event1 = Event.new
39
+            event1.agent = agents(:bob_weather_agent)
40
+            event1.payload = {
41
+                :xyz => "value1",
42
+                :message => "value2"
43
+            }
44
+
45
+            lambda {
46
+                @checker.receive([@event,event1])
47
+            }.should change { Event.count }.by(2)
48
+        end
49
+    end
50
+
51
+    describe "#working?" do
52
+        it "checks if events have been received within expected receive period" do
53
+            @checker.should_not be_working
54
+            Agents::TranslationAgent.async_receive @checker.id, [@event.id]
55
+            @checker.reload.should be_working
56
+            two_days_from_now = 2.days.from_now
57
+            stub(Time).now { two_days_from_now }  
58
+            @checker.reload.should_not be_working
59
+        end
60
+    end
61
+
62
+    describe "validation" do
63
+        before do
64
+            @checker.should be_valid
65
+        end
66
+
67
+        it "should validate presence of content key" do
68
+            @checker.options[:content] = nil
69
+            @checker.should_not be_valid
70
+        end
71
+
72
+        it "should validate presence of expected_receive_period_in_days key" do
73
+            @checker.options[:expected_receive_period_in_days] = nil
74
+            @checker.should_not be_valid
75
+        end
76
+
77
+        it "should validate presence of client_id key" do
78
+            @checker.options[:client_id] = ""
79
+            @checker.should_not be_valid
80
+        end
81
+
82
+        it "should validate presence of client_secret key" do
83
+            @checker.options[:client_secret] = ""
84
+            @checker.should_not be_valid
85
+        end
86
+
87
+        it "should validate presence of 'to' key" do
88
+            @checker.options[:to] = ""
89
+            @checker.should_not be_valid
90
+        end
91
+    end
92
+end